#include "include/hal_i2c.h"
#include <iostream>

HAL::I2C_Master::I2C_Master(const std::string &dev)
{
    this->dev = dev;
    this->fd = open(this->dev.c_str(), O_RDWR | O_NONBLOCK);
    if (this->fd < 0)
    {
        std::cerr << "I2C_Master: open " << this->dev << " failed" << std::endl;
        return;
    }
}
HAL::I2C_Master::~I2C_Master()
{
    if (this->fd >= 0)
    {
        close(this->fd);
        this->fd = -1;
    }
}

int HAL::I2C_Master::ReadReg(uint8_t addr, uint8_t reg, uint8_t *data, size_t len)
{
    std::lock_guard<std::mutex> lock(this->mtx);
    if (this->fd < 0)
    {
        std::cerr << "I2C_Master: open " << this->dev << " failed" << std::endl;
        return -1;
    }

    //设置地址长度：0为7位地址
    ioctl(fd,I2C_TENBIT,0);
    //设置从机地址
    if (ioctl(fd,I2C_SLAVE,addr) < 0)
    {
        std::cerr << "I2C_Master: set slave addr failed" << std::endl;
        return -1;
    }

    //设置收不到ACK时的重试次数
    ioctl(fd,I2C_RETRIES,3);

    //写入寄存器地址
    if (write(fd,&reg,1) != 1)
    {
        std::cerr << "I2C_Master: write reg failed" << std::endl;
        return -1;
    }
    //读取数据
    if (read(fd,data,len) != len)
    {
        std::cerr << "I2C_Master: read data failed" << std::endl;
        return -1;
    }

    //返回读取数据的长度
    return len;
}

int HAL::I2C_Master::WriteReg(uint8_t addr, uint8_t reg, uint8_t *data, size_t len)
{
    std::lock_guard<std::mutex> lock(this->mtx);
    if (this->fd < 0)
    {
        std::cerr << "I2C_Master: open " << this->dev << " failed" << std::endl;
        return -1;
    }
    
    //设置地址长度：0为7位地址
    ioctl(fd,I2C_TENBIT,0);
    //设置从机地址
    if (ioctl(fd,I2C_SLAVE,addr) < 0)
    {
        std::cerr << "I2C_Master: set slave addr failed" << std::endl;
        return -1;
    }

    //设置收不到ACK时的重试次数
    ioctl(fd,I2C_RETRIES,3);

    //写入寄存器地址
    if (write(fd,&reg,1) != 1)
    {
        std::cerr << "I2C_Master: write reg failed" << std::endl;
        return -1;
    }
    //写入数据
    if (write(fd,data,len) != len)
    {
        std::cerr << "I2C_Master: write data failed" << std::endl;
        return -1;
    }

    //返回写入数据的长度
    return len;
}